package com.czl.elm.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.czl.elm.dao.RedParperMapper;
import com.czl.elm.dao.ShopMapper;
import com.czl.elm.domain.RedParper;
import com.czl.elm.domain.Seckill;
import com.czl.elm.domain.Shop;
import com.czl.elm.domain.UsersLoginParam;
import com.czl.elm.service.ISeckillService;
import com.czl.elm.util.ActionResult;
import com.czl.elm.util.PageHelper;
import com.czl.elm.util.RespPageBean;
import com.czl.elm.util.TimeUtil;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.swing.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

@Service
public class SeckillServiceImpl implements ISeckillService {
    @Autowired
    private RedParperMapper redParperMapper;
    @Autowired
    private RedParperServiceImpl redParperService;
    @Autowired
    private ShopMapper shopMapper;
    @Autowired
    private RedisTemplate redisTemplate;


    @Override
    @Transactional(rollbackFor=Exception.class)
    public void doSeckill(String seckillId,String phoneName) {
        ValueOperations<String, Object> redisString = redisTemplate.opsForValue();

        String header="seckill_";

        int res=redParperMapper.doSeckill(seckillId);
        if(res==1){
            Seckill seckill=getSeckillById(seckillId);
            String redParperId=header+seckillId+phoneName;
            RedParper result=redParperService.createRedParper(phoneName,seckill,header,redParperId);
            redisString.set(redParperId,1);

        }else{
            redisTemplate.opsForValue().set("fail_"+seckillId+phoneName,1);
        }

    }

    @Override
    public ActionResult getSeckillResult(String seckillId) {
        String phoneName= ((UsersLoginParam) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getPhoneName();
        if(redisTemplate.opsForValue().get("fail_"+seckillId+phoneName)!=null)return ActionResult.error("库存不足",500);
        String res=redParperMapper.getSeckillResult(phoneName,seckillId);

        if(res==null){
            System.out.println(seckillId);
            return ActionResult.success("排队中",0);
        }
        return ActionResult.success("秒杀成功",res);
    }

    @Override
    public ActionResult SeckillNum(String redShopParperId) {
        Integer res=redParperMapper.getSeckillNumber(redShopParperId);
        if(res==null)return ActionResult.error("获取失败");
        return ActionResult.success("获取成功",res);
    }

    @Override
    public ActionResult checkSeckill(String redShopParperId) {
        Boolean res=getCheckSeckill(redShopParperId);
        if(res){
            return ActionResult.error("该用户抢过了");
        }else{
            return ActionResult.success("该用户还没抢过");
        }

    }

    /**
     * 获取秒杀活动剩余个数
     * @param redShopParperId
     * @return
     */
    @Override
    public Integer getSeckillNum(String redShopParperId){
        return redParperMapper.getSeckillNumber(redShopParperId);
    }

    /**
     * 获取该用户是否已经参与了秒杀
     * 是返回1  不是返回0
     * @param redShopParperId
     * @return
     */
    private Boolean getCheckSeckill(String redShopParperId){
        String phoneName= ((UsersLoginParam) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getPhoneName();
        int res=redParperMapper.getCheckSeckill(phoneName,redShopParperId);
        if(res!=0)return true;
        else return false;
    }

    /**
     * 通过id来获取秒杀活动
     * @param redShopParperId
     * @return
     */
    private Seckill getSeckillById(String redShopParperId){
        return redParperMapper.getSeckillById(redShopParperId);
    }

    /**
     * 商家添加秒杀优惠券
     * 优惠券格式
     * {
     * "shopId":0,
     * "afterTime":172800,
     * "fullReduction":5000,
     * "reduction":4000,
     * "enable":1,
     * "redpaperNum":500,
     * "killTime":"2021-06-10 14:00:00"
     *
     * }
     * startTime选填
     * endTime和afterTime 任选其一
     * @param msg
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ActionResult addSeckillParper(Map<String, Object> msg) {
        Seckill seckill=new Seckill();
        Integer shopId= (Integer) msg.get("shopId");
        if(shopId!=0){
            Shop shop=shopMapper.selectShopBasicById(shopId);
            seckill.setShopUrl(shop.getShopUrl());
            seckill.setShopId(shopId);
        }else{
            seckill.setShopUrl("/shop/elm.png");
            seckill.setShopId(shopId);
        }
        seckill.setSeckillName((String)msg.get("seckillName"));
        seckill.setRedShopParperId("Seckill_shopid"+msg.get("shopId")+"_"+System.currentTimeMillis());
        seckill.setEnable((Integer)msg.get("enable"));
        seckill.setShopId((Integer)msg.get("shopId"));
        seckill.setRedpaperNum((Integer) msg.get("redpaperNum"));
        seckill.setAfterTime((Integer) msg.get("afterTime"));
        String start=(String)msg.getOrDefault("startTime",null);
        String end=(String)msg.getOrDefault("endTime",null);

        String killtime=(String) msg.get("killTime");
        //System.out.println(killtime);
        LocalDateTime killTime=null;
        if(killtime!=null)killTime= TimeUtil.StringToLocalDateTime(killtime);
        seckill.setKillTime(killTime);
        LocalDateTime startTime;
        if(start!=null){
            startTime=TimeUtil.StringToLocalDateTime(start);
        }else{
            startTime=killTime;
        }
        LocalDateTime endTime;
        if(end!=null)endTime=TimeUtil.StringToLocalDateTime(end);
        else{
            endTime=startTime.plusSeconds((Integer)msg.get("afterTime"));
        }
        seckill.setStartTime(startTime);
        seckill.setEndTime(endTime);
        seckill.setReduction((Integer)msg.get("reduction"));
        seckill.setFullReduction((Integer)msg.get("fullReduction"));

        redParperMapper.addShopRedParper(seckill);
        redParperMapper.addSeckillParper(seckill);
        return ActionResult.success("添加成功");
    }

    @Override
    public ActionResult seckillList(String killTime, Integer currentPage, Integer size) {
        if(killTime==null){
            return ActionResult.error("时间格式错误");
        }

        LocalDateTime time=TimeUtil.StringToLocalDateTime(killTime);
        Page<RedParper> page=new Page<>(currentPage,size);
        LocalDateTime now=LocalDateTime.now();
        IPage<Seckill> res_page=redParperMapper.seckillList(now,time,page);
        RespPageBean res=new RespPageBean(res_page.getTotal(),res_page.getRecords());
        return ActionResult.success("获取成功",res);
    }

    @Override
    public ActionResult seckillListbyuser( String killTime) {
        String phoneName= ((UsersLoginParam) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getPhoneName();

        LocalDateTime time=TimeUtil.StringToLocalDateTime(killTime);

        List<String> res=redParperMapper.seckillListbyuser(phoneName,time);
        if(res==null)return ActionResult.error("获取失败");
        return ActionResult.success("获取成功",res);
    }

    @Override
    public List<Seckill> getAllSeckill() {
        LocalDateTime now=LocalDateTime.now();
        List<Seckill> res=redParperMapper.getAllSeckill(now);
        return res;
    }



}
